#include "StdAfx.hpp"
#include "Material.hpp"
#include "Engine.hpp"
#include "Texture.hpp"
#include "Scene.hpp"


Material::Material()
: Type(TYPE_NORMAL)
, CullMode(D3DCULL_CCW)
, FillMode(D3DFILL_SOLID)
, ConstantColorEnabled(false)
, ConstantColor(COLORF_WHITE)
, VertexColorEnabled(false)
, SpecularIntensity(0.f)
, SpecularExponent(32.f)
, CastShadow(true)
, BlendOp(D3DBLENDOP_ADD)
, SrcBlend(D3DBLEND_SRCALPHA)
, DstBlend(D3DBLEND_INVSRCALPHA)
, AlphaTestEnabled(false)
, AlphaTestRef(0.5f)
//, AlphaTestFunc(D3DCMP_GREATEREQUAL)
, m_Texture(NULL)
, FresnelEnabled(false)
, FresnelColor(COLORF_WHITE)
, FresnelExponent(1.f)
, EnvMappingEnabled(true)
, EnvMappingColor(COLORF_WHITE)
, NormalMappingEnabled(true)
, m_EnvMappingTexture(NULL)
, m_NormalTexture(NULL)
{

}

Material::~Material()
{
	SAFE_RELEASE(m_NormalTexture);
	SAFE_RELEASE(m_EnvMappingTexture);
	SAFE_RELEASE(m_Texture);
}

bool Material::IsUsingFresnel()
{
	return FresnelEnabled
		&& FresnelColor.A > FLT_EPSILON
		&& (FresnelColor.R > FLT_EPSILON || FresnelColor.G > FLT_EPSILON || FresnelColor.B > FLT_EPSILON);
}

bool Material::IsUsingEnvMapping()
{
	return EnvMappingEnabled
		&& (EnvMappingColor.R > FLT_EPSILON || EnvMappingColor.G > FLT_EPSILON || EnvMappingColor.B > FLT_EPSILON);
}

bool Material::IsUsingAlphaTest()
{
	return AlphaTestEnabled && AlphaTestRef > FLT_EPSILON;

	/*if (!AlphaTestEnabled)
		return false;
	switch (AlphaTestFunc)
	{
	case D3DCMP_ALWAYS:
		return false;
	case D3DCMP_NEVER:
	case D3DCMP_EQUAL:
	case D3DCMP_NOTEQUAL:
	case D3DCMP_LESS:
	case D3DCMP_GREATER:
		return true;
	case D3DCMP_LESSEQUAL:
		return AlphaTestRef < 255;
	case D3DCMP_GREATEREQUAL:
		return AlphaTestRef > 0;
	default:
		assert(0); return false;
	}*/
}

void Material::SetTexture( D3dTexture *v )
{
	UpdateObjPtr(m_Texture, v);
}

void Material::SetEnvMappingTexture( D3dTexture *v )
{
	UpdateObjPtr(m_EnvMappingTexture, v);
}

void Material::SetNormalTexture( D3dTexture *v )
{
	UpdateObjPtr(m_NormalTexture, v);
}

uint Material::CalcRenderingPasses()
{
	uint r = 0;
	if (CastShadow)
		r |= RENDER_PASS_SHADOW_MAP;
	switch (Type)
	{
	case TYPE_NORMAL:
		r |= RENDER_PASS_GBUFFER;
		break;
	case TYPE_EMISSIVE:
		r |= RENDER_PASS_GBUFFER | RENDER_PASS_FORWARD;
		break;
	case TYPE_TRANSLUCENT:
		r |= RENDER_PASS_FORWARD;
		break;
	default:
		assert(0);
	}
	if (IsUsingFresnel() || IsUsingEnvMapping())
		r |= RENDER_PASS_FORWARD;
	return r;
}
